Add focus to pirqs and interdomain evtchns.
u8 nr_guests;
u8 in_flight;
u8 shareable;
- struct domain *guest[IRQ_MAX_GUESTS];
+ struct exec_domain *guest[IRQ_MAX_GUESTS];
} irq_guest_action_t;
static void __do_IRQ_guest(int irq)
{
irq_desc_t *desc = &irq_desc[irq];
irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
- struct domain *d;
+ struct exec_domain *ed;
int i;
for ( i = 0; i < action->nr_guests; i++ )
{
- d = action->guest[i];
- if ( !test_and_set_bit(irq, &d->pirq_mask) )
+ ed = action->guest[i];
+ if ( !test_and_set_bit(irq, &ed->domain->pirq_mask) )
action->in_flight++;
- send_guest_pirq(d, irq);
+ send_guest_pirq(ed, irq);
}
}
return 0;
}
-int pirq_guest_bind(struct domain *d, int irq, int will_share)
+int pirq_guest_bind(struct exec_domain *ed, int irq, int will_share)
{
+ struct domain *d = ed->domain;
irq_desc_t *desc = &irq_desc[irq];
irq_guest_action_t *action;
unsigned long flags;
goto out;
}
- action->guest[action->nr_guests++] = d;
+ action->guest[action->nr_guests++] = ed;
out:
spin_unlock_irqrestore(&desc->lock, flags);
else
{
i = 0;
- while ( action->guest[i] != d )
+ while ( action->guest[i] && action->guest[i]->domain != d )
i++;
memmove(&action->guest[i], &action->guest[i+1], IRQ_MAX_GUESTS-i-1);
action->nr_guests--;
{
#define ERROR_EXIT(_errno) do { rc = (_errno); goto out; } while ( 0 )
struct domain *d1, *d2;
+ struct exec_domain *ed1, *ed2;
int port1 = bind->port1, port2 = bind->port2;
domid_t dom1 = bind->dom1, dom2 = bind->dom2;
long rc = 0;
return -ESRCH;
}
+ ed1 = d1->exec_domain[0]; /* XXX */
+ ed2 = d2->exec_domain[0]; /* XXX */
+
/* Avoid deadlock by first acquiring lock of domain with smaller id. */
if ( d1 < d2 )
{
break;
case ECS_INTERDOMAIN:
- if ( d1->event_channel[port1].u.interdomain.remote_dom != d2 )
+ if ( d1->event_channel[port1].u.interdomain.remote_dom != ed2 )
ERROR_EXIT(-EINVAL);
if ( (d1->event_channel[port1].u.interdomain.remote_port != port2) &&
(bind->port2 != 0) )
break;
case ECS_INTERDOMAIN:
- if ( d2->event_channel[port2].u.interdomain.remote_dom != d1 )
+ if ( d2->event_channel[port2].u.interdomain.remote_dom != ed1 )
ERROR_EXIT(-EINVAL);
if ( (d2->event_channel[port2].u.interdomain.remote_port != port1) &&
(bind->port1 != 0) )
* Everything checked out okay -- bind <dom1,port1> to <dom2,port2>.
*/
- d1->event_channel[port1].u.interdomain.remote_dom = d2;
+ d1->event_channel[port1].u.interdomain.remote_dom = ed2;
d1->event_channel[port1].u.interdomain.remote_port = (u16)port2;
d1->event_channel[port1].state = ECS_INTERDOMAIN;
- d2->event_channel[port2].u.interdomain.remote_dom = d1;
+ d2->event_channel[port2].u.interdomain.remote_dom = ed1;
d2->event_channel[port2].u.interdomain.remote_port = (u16)port1;
d2->event_channel[port2].state = ECS_INTERDOMAIN;
goto out;
d->pirq_to_evtchn[pirq] = port;
- rc = pirq_guest_bind(d, pirq,
+ rc = pirq_guest_bind(current, pirq,
!!(bind->flags & BIND_PIRQ__WILL_SHARE));
if ( rc != 0 )
{
case ECS_INTERDOMAIN:
if ( d2 == NULL )
{
- d2 = chn1[port1].u.interdomain.remote_dom;
+ d2 = chn1[port1].u.interdomain.remote_dom->domain;
/* If we unlock d1 then we could lose d2. Must get a reference. */
if ( unlikely(!get_domain(d2)) )
goto again;
}
}
- else if ( d2 != chn1[port1].u.interdomain.remote_dom )
+ else if ( d2 != chn1[port1].u.interdomain.remote_dom->domain )
{
rc = -EINVAL;
goto out;
BUG();
if ( chn2[port2].state != ECS_INTERDOMAIN )
BUG();
- if ( chn2[port2].u.interdomain.remote_dom != d1 )
+ if ( chn2[port2].u.interdomain.remote_dom->domain != d1 )
BUG();
chn2[port2].state = ECS_UNBOUND;
static long evtchn_send(int lport)
{
- struct domain *ld = current->domain, *rd;
+ struct domain *ld = current->domain;
+ struct exec_domain *rd;
int rport;
spin_lock(&ld->event_channel_lock);
break;
case ECS_INTERDOMAIN:
status->status = EVTCHNSTAT_interdomain;
- status->u.interdomain.dom = chn[port].u.interdomain.remote_dom->id;
+ status->u.interdomain.dom =
+ chn[port].u.interdomain.remote_dom->domain->id;
status->u.interdomain.port = chn[port].u.interdomain.remote_port;
break;
case ECS_PIRQ:
* may require explicit memory barriers.
*/
-static inline void evtchn_set_pending(struct domain *d, int port)
+static inline void evtchn_set_pending(struct exec_domain *ed, int port)
{
- struct exec_domain *ed = d->exec_domain[0];
+ struct domain *d = ed->domain;
shared_info_t *s = d->shared_info;
int running;
*/
static inline void send_guest_virq(struct exec_domain *ed, int virq)
{
- struct domain *d = ed->domain;
- evtchn_set_pending(d, d->virq_to_evtchn[virq]);
+ evtchn_set_pending(ed, ed->domain->virq_to_evtchn[virq]);
}
/*
* @d: Domain to which physical IRQ should be sent
* @pirq: Physical IRQ number
*/
-static inline void send_guest_pirq(struct domain *d, int pirq)
+static inline void send_guest_pirq(struct exec_domain *ed, int pirq)
{
- evtchn_set_pending(d, d->pirq_to_evtchn[pirq]);
+ evtchn_set_pending(ed, ed->domain->pirq_to_evtchn[pirq]);
}
#define event_pending(_d) \
extern void no_action(int cpl, void *dev_id, struct xen_regs *regs);
struct domain;
+struct exec_domain;
extern int pirq_guest_unmask(struct domain *p);
-extern int pirq_guest_bind(struct domain *p, int irq, int will_share);
+extern int pirq_guest_bind(struct exec_domain *p, int irq, int will_share);
extern int pirq_guest_unbind(struct domain *p, int irq);
extern int pirq_guest_bindable(int irq, int will_share);
domid_t remote_domid;
} __attribute__ ((packed)) unbound; /* state == ECS_UNBOUND */
struct {
- u16 remote_port;
- struct domain *remote_dom;
+ u16 remote_port;
+ struct exec_domain *remote_dom;
} __attribute__ ((packed)) interdomain; /* state == ECS_INTERDOMAIN */
u16 pirq; /* state == ECS_PIRQ */
u16 virq; /* state == ECS_VIRQ */